package com.itheima.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.itheima.constant.MessageConstant;
import com.itheima.entity.Result;
import com.itheima.service.MemberService;
import com.itheima.service.ReportService;
import com.itheima.service.SetmealService;
import com.itheima.utils.DateTimeUtil;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.util.*;

@RestController
@RequestMapping("/report")
public class ReportController {
    @Reference
    private MemberService memberService;
    @Reference
    private SetmealService setmealService;
    @Reference
    private ReportService reportService;

    /**
     * 过去一年时间内每个月的会员总数据(累加的)量
     * months:['2019-01','2019-02','2019-03','2019-04']
     * memberCounts:[1,5,7,8]
     *
     * @return
     */
    @RequestMapping("/getMemberReport")
    public Result getMemberReport() {
        try {
            // 计算出月份
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.MONTH, -11);
            //组装月份数据
            List<String> month_param = new ArrayList<String>(12);
            List<String> months = new ArrayList<String>(12);
            for (int i = 0; i < 12; i++) {
                Date date01 = calendar.getTime();
                months.add(DateTimeUtil.getStringByDate(date01, "yyyy-MM"));
                calendar.add(Calendar.MONTH, 1);
                Date date = calendar.getTime();
                String month = DateTimeUtil.getStringByDate(date, "yyyy-MM");
                month_param.add(month);
            }
            //查询会员数量
            List<Integer> memberCounts = memberService.findCountByMonths(month_param);
            Map<String, Object> map = new HashMap<String, Object>(2);
            map.put("months", months);
            map.put("memberCounts", memberCounts);
            return new Result(true, MessageConstant.GET_MEMBER_NUMBER_REPORT_SUCCESS, map);
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(false, MessageConstant.GET_MEMBER_NUMBER_REPORT_FAIL);
        }
    }

    @RequestMapping("/getMemberReportBetweenDays")
    public Result getMemberReportBetweenDays(String start, String end) {
        try {
            Date date01 = DateTimeUtil.getDateByString(start, "yyyy-MM-dd");
            Date date02 = DateTimeUtil.getDateByString(end, "yyyy-MM-dd");
            List<String> months = new ArrayList<String>();
            List<String> months_param = new ArrayList<String>();
            while (date01.getTime() <= date02.getTime()) {
                months.add(DateTimeUtil.getStringByDate(date01, "yyyy-MM"));
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(date01);
                calendar.add(Calendar.MONTH, 1);
                Date date = calendar.getTime();
                months_param.add(DateTimeUtil.getStringByDate(date, "yyyy-MM"));
                date01 = date;
            }
            List<Integer> memberCounts = memberService.findCountByMonths(months_param);
            Map<String, Object> map = new HashMap<String, Object>(2);
            map.put("months", months);
            map.put("memberCounts", memberCounts);

//            memberService.
            return new Result(true, MessageConstant.GET_MEMBER_NUMBER_REPORT_SUCCESS, map);
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(false, MessageConstant.GET_MEMBER_NUMBER_REPORT_FAIL);
        }
    }

    @RequestMapping("/getMemberReportByAge")
    public Result getMemberReportByAge() {
        try {
            List<String> ageList = new ArrayList<>();
            List<Map<String, String>> valueMapList = new ArrayList<>();
            ageList.add("0-17");
            ageList.add("18-30");
            ageList.add("31-60");
            ageList.add("61-");
            int size = ageList.size();
            for (int i = 0; i < size; i++) {
                HashMap<String, String> temp = new HashMap<>();
                String str = ageList.get(i);
                String[] split = str.split("-");
                temp.put("start", split[0]);
                if (split.length == 2) temp.put("end", split[1]);
                int count = memberService.findCountByAge(temp);
                if (split.length < 2) str = str.replace("-", "以上");
                ageList.set(i, str);
                temp.clear();
                temp.put("name", str);
                temp.put("value", count + "");
                valueMapList.add(temp);
            }
            Map<String, Object> resultData = new HashMap<String, Object>(2);
            resultData.put("names", ageList);
            resultData.put("counts", valueMapList);
            return new Result(true, MessageConstant.GET_MEMBER_NUMBER_REPORT_SUCCESS, resultData);
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(false, MessageConstant.GET_MEMBER_NUMBER_REPORT_FAIL);
        }
    }

    @RequestMapping("/getMemberReportBySex")
    public Result getMemberReportBySex() {
        try {
            List<Map> counts = memberService.getCountsBySex();
            List<String> names = new ArrayList<>(3);
            for (Map count : counts) {
                if (count.get("name").equals("1")) {
                    count.put("name", "女");
                } else if (count.get("name").equals("2")) {
                    count.put("name", "男");
                }
                names.add((String) count.get("name"));
            }
            Map<String, Object> resultData = new HashMap<String, Object>(2);
            resultData.put("names", names);
            resultData.put("counts", counts);
            return new Result(true, MessageConstant.GET_MEMBER_NUMBER_REPORT_SUCCESS, resultData);
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(false, MessageConstant.GET_MEMBER_NUMBER_REPORT_FAIL);
        }
    }

    /**
     * "setmealNames":["入职体检套餐","儿童体检套餐"],
     * "setmealCounts":[
     * {"value":50,"name":"入职体检套餐"},
     * {"value":60,"name":"儿童体检套餐"}
     * ]
     *
     * @return
     */
    @RequestMapping("/getSetmealReport")
    public Result getSetmealReport() {
        try {
            Map<String, Object> resultMap = new HashMap<String, Object>(2);
            List<Map<String, Object>> setmealCounts = setmealService.findSetmealCounts();
            resultMap.put("setmealCounts", setmealCounts);
            List<String> setmealNames = new ArrayList<String>(setmealCounts.size());
            for (Map<String, Object> map : setmealCounts) {
                setmealNames.add(map.get("name").toString());
            }
            resultMap.put("setmealNames", setmealNames);
            return new Result(true, MessageConstant.GET_SETMEAL_COUNT_REPORT_SUCCESS, resultMap);
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(false, MessageConstant.GET_SETMEAL_COUNT_REPORT_FAIL);
        }
    }

    /**
     * reportDate:'2020-02-17',
     * todayNewMember :0,
     * totalMember :0,
     * thisWeekNewMember :0,
     * thisMonthNewMember :0,
     * todayOrderNumber :0,
     * todayVisitsNumber :0,
     * thisWeekOrderNumber :0,
     * thisWeekVisitsNumber :0,
     * thisMonthOrderNumber :0,
     * thisMonthVisitsNumber :0,
     * hotSetmeal :[
     * {name:'阳光爸妈升级肿瘤12项筛查（男女单人）体检套餐',setmeal_count:200,proportion:0.222},
     * {name:'阳光爸妈升级肿瘤12项筛查体检套餐',setmeal_count:200,proportion:0.222}
     * ]
     *
     * @return
     */
    @RequestMapping("/getBusinessReportData")
    public Result getBusinessReportData() {
        try {
            Map<String, Object> resultMap = new HashMap<String, Object>();
            resultMap = reportService.getBusinessReport();
            return new Result(true, MessageConstant.GET_BUSINESS_REPORT_SUCCESS, resultMap);
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(false, MessageConstant.GET_BUSINESS_REPORT_FAIL);
        }
    }

    /**
     * reportDate:'2020-02-17',
     * todayNewMember :0,
     * totalMember :0,
     * thisWeekNewMember :0,
     * thisMonthNewMember :0,
     * todayOrderNumber :0,
     * todayVisitsNumber :0,
     * thisWeekOrderNumber :0,
     * thisWeekVisitsNumber :0,
     * thisMonthOrderNumber :0,
     * thisMonthVisitsNumber :0,
     * hotSetmeal :[
     * {name:'阳光爸妈升级肿瘤12项筛查（男女单人）体检套餐',setmeal_count:200,proportion:0.222},
     * {name:'阳光爸妈升级肿瘤12项筛查体检套餐',setmeal_count:200,proportion:0.222}
     * ]
     * .xls .xlsx
     *
     * @return
     */
    @RequestMapping("/exportBusinessReport")
    public Result exportBusinessReport(HttpServletRequest request, HttpServletResponse response) {
        try {
//            + 查询出报表所需要的业务数据
            Map<String, Object> resultMap = reportService.getBusinessReport();
            //获取excel模板的绝对路径(request.getSession().getServletContext() 定位webapp目录下)
            String realPath = request.getSession().getServletContext().getRealPath("template/report_template.xlsx");
            //使用输入流读取excel模板文件
            XSSFWorkbook workbook = new XSSFWorkbook(new FileInputStream(new File(realPath)));
            XSSFSheet sheet = workbook.getSheetAt(0);
//            + 取出业务数据，向excel模板中对应的单元格插入数据
            //处理日期
            XSSFRow row = sheet.getRow(2);
            row.getCell(5).setCellValue(resultMap.get("reportDate").toString());
            //处理本日新增会员
            row = sheet.getRow(4);
            row.getCell(5).setCellValue(resultMap.get("todayNewMember").toString());
            //处理总会员数
            row.getCell(7).setCellValue(resultMap.get("totalMember").toString());
            //处理本周新增会员数&本月新增会员数
            row = sheet.getRow(5);
            row.getCell(5).setCellValue(resultMap.get("thisWeekNewMember").toString());
            row.getCell(7).setCellValue(resultMap.get("thisMonthNewMember").toString());
            //处理今日预约数&今日到诊数
            row = sheet.getRow(7);
            row.getCell(5).setCellValue(resultMap.get("todayOrderNumber").toString());
            row.getCell(7).setCellValue(resultMap.get("todayVisitsNumber").toString());
            //处理本周预约数&本周到诊数
            row = sheet.getRow(8);
            row.getCell(5).setCellValue(resultMap.get("thisWeekOrderNumber").toString());
            row.getCell(7).setCellValue(resultMap.get("thisWeekVisitsNumber").toString());
            //处理本月预约数&本月到诊数
            row = sheet.getRow(9);
            row.getCell(5).setCellValue(resultMap.get("thisMonthOrderNumber").toString());
            row.getCell(7).setCellValue(resultMap.get("thisMonthVisitsNumber").toString());
            //处理热门套餐
            List<Map<String, Object>> hotSetmeal = (List<Map<String, Object>>) resultMap.get("hotSetmeal");
            //遍历循环热门套餐数据
            for (int i = 0; i < hotSetmeal.size(); i++) {
                Map<String, Object> tempMap = hotSetmeal.get(i);
                row = sheet.getRow(12 + i);
                row.getCell(4).setCellValue(tempMap.get("name").toString());
                row.getCell(5).setCellValue(tempMap.get("setmeal_count").toString());
                row.getCell(6).setCellValue(Double.valueOf(tempMap.get("proportion").toString()));
            }
//            + 通过输出流，响应【浏览器下载】
            ServletOutputStream out = response.getOutputStream();
            response.setContentType("application/vnd.ms-excel");
            response.setHeader("content-Disposition", "attachment;filename=report.xlsx");
            workbook.write(out);

            out.flush();
            out.close();
            workbook.close();
            return new Result(true, MessageConstant.GET_BUSINESS_REPORT_SUCCESS);
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(false, MessageConstant.GET_BUSINESS_REPORT_FAIL);
        }
    }
}
